/*
 * Copyright (c) 2022. China Mobile (SuZhou) Software Technology Co.,Ltd. All rights reserved.
 * Lakehouse is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

package com.chinamobile.cmss.lakehouse.api.service.impl;

import com.chinamobile.cmss.lakehouse.api.service.UserSessionService;
import com.chinamobile.cmss.lakehouse.common.Constants;
import com.chinamobile.cmss.lakehouse.common.utils.UUIDUtil;
import com.chinamobile.cmss.lakehouse.dao.UserSessionDao;
import com.chinamobile.cmss.lakehouse.dao.entity.UserEntity;
import com.chinamobile.cmss.lakehouse.dao.entity.UserSessionEntity;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Slf4j
public class UserSessionServiceImpl extends BaseServiceImpl implements UserSessionService {

    @Resource
    UserSessionDao userSessionDao;

    /**
     * create user session
     *
     * @param user user
     * @param ip   ip
     * @return session string
     */
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public String createUserSession(UserEntity user, String ip) {
        UserSessionEntity userSession = null;

        // logined
        List<UserSessionEntity> sessionList = userSessionDao.findByUserIdAndIp(user.getUserName(), ip);

        Date now = new Date();

        /**
         * if you have logged in and are still valid, return directly
         */
        if (CollectionUtils.isNotEmpty(sessionList)) {
            // is session list greater 1 ， delete other ，get one
            if (sessionList.size() > 1) {
                for (int i = 1; i < sessionList.size(); i++) {
                    userSessionDao.deleteById(sessionList.get(i).getId());
                }
            }
            userSession = sessionList.get(0);
            if (now.getTime() - userSession.getLastLoginTime().getTime() <= Constants.SESSION_TIME_OUT * 1000) {
                /**
                 * updateProcessInstance the latest login time
                 */
                userSessionDao.save(userSession);
                return userSession.getUuid();
            } else {
                /**
                 * session expired, then delete this session first
                 */
                userSessionDao.deleteById(userSession.getId());
            }
        }

        // assign new session
        userSession = UserSessionEntity.builder()
            .uuid(UUIDUtil.generateUuid())
            .ip(ip)
            .userId(user.getUserName())
            .build();

        userSessionDao.save(userSession);

        return userSession.getUuid();
    }

    /**
     * get user session
     *
     * @param sessionId session id
     * @return user session
     */
    @Override
    public UserSessionEntity getSession(String sessionId) {
        return userSessionDao.findByUuid(sessionId);
    }

    /**
     * sign out
     *
     * @param ip        ip
     * @param loginUser login user
     */
    @Override
    public void signOut(String ip, UserEntity loginUser) {
        userSessionDao.deleteByUserIdAndIp(loginUser.getUserName(), ip);
    }
}
